/**
 * bushaofeng. 2011.8.25
 * bs_struct.h：基本数据结构定义
 * history:
 */

#ifndef __BS_STRUCT_H_
#define __BS_STRUCT_H_

#include "bs_type.h"
#include "bs_def.h"
#include "bs_error.h"

#ifdef __cplusplus
extern "C"{
#endif

/* array结构 */
typedef struct _bs_array_t     _bs_array_t;

struct _bs_array_t{
    size_t      len;
    size_t      size;
    size_t      esize;
    void*       elem;
};

#define array_t(type)   struct{                 \
    size_t      vlen;                           \
    size_t      size;                           \
    size_t      esisze;                         \
    type*     elem;                           \
}

int _bs_array_init(_bs_array_t* array, size_t esize);
int _bs_array_init_len(_bs_array_t* array, size_t esize, int len);
int _bs_array_add(_bs_array_t* array, void* elem, size_t esize); 
int _bs_array_get(_bs_array_t* array, void* elem, uint32_t i);
void* _bs_array_get_ptr(_bs_array_t* array, uint32_t i);

#define array_type(type, name)      typedef array_t(type) name
#define array_init(array)           _bs_array_init((_bs_array_t*)(array), sizeof(*(array)->elem))
#define array_init_len(array, len)  _bs_array_init_len((_bs_array_t*)(array), sizeof(*(array)->elem), len)
#define array_push(array, elem)     _bs_array_add((_bs_array_t*)(array), &(elem), sizeof(elem))
#define array_get(array, elem, i)   _bs_array_get((_bs_array_t*)(array), &(elem), (i))
#define array_getptr(array, i)     _bs_array_get_ptr((_bs_array_t*)(array), (i))
#define array_getlen(array)     (((_bs_array_t*)(array))->len)
#define array_destroy(array)    free((array)->elem)

/* list结构 */
typedef struct _list_t          _list_t;
typedef struct _list_elem_t     _list_elem_t;

struct _list_elem_t{
    _list_elem_t*       prev;
    _list_elem_t*       next;
    void*               elem;
};

struct _list_t{
    _list_elem_t        head;
    _list_elem_t        rear;
    size_t              size;
    size_t              elen;
};

#define LIST_DEFINE(type, name) typedef list_t(type) name

#define list_t(type)    struct{                 \
    _list_elem_t        head;                   \
    _list_elem_t        rear;                   \
    size_t              size;                   \
    size_t              elen;                   \
    type                etype;                  \
}

#define list_define(type, name) typedef list_t(type) name

#define list_init(list)                 do{     \
    (list)->head.prev = NULL;                   \
    (list)->head.next = &(list)->rear;          \
    (list)->head.elem = &(list)->head;          \
    (list)->rear.prev = &(list)->head;          \
    (list)->rear.next = NULL;                   \
    (list)->rear.elem = &(list)->rear;          \
    list_size(list) = 0;                        \
    list_elen(list) = sizeof((list)->etype);    \
}while(0)
#define list_free(list)         _list_free((_list_t*)(list))
#define list_head(list)         ((list)->head.next==&(list)->rear ? NULL:(list)->head.next->elem)
#define list_rear(list)         ((list)->rear.prev==&(list)->head ? NULL:(list)->rear.prev->elem)
#define list_size(list)         ((list)->size)
#define list_elen(list)         ((list)->elen)

#define elem_addr(elem)         ((_list_elem_t*)((char*)(elem)-sizeof(_list_elem_t)))
#define elem_next(elem)         (elem_addr(elem)->next)
#define elem_prev(elem)         (elem_addr(elem)->prev)
#define elem_elem(data)         ((data)->elem)

#define list_next(elem)         (elem_elem(elem_next(elem)))
#define list_prev(elem)         (elem_elem(elem_prev(elem)))
#define list_forward(list, elem)        ((void*)(elem) != (void*)&(list)->rear)
#define list_back(list, elem)           ((void*)(elem) != (void*)&(list)->head)

#define list_insert_rear(list, elem)    _list_insert_rear((_list_t*)(list), (elem))
#define list_insert_head(list, elem)    _list_insert_head((_list_t*)(list), (elem))
#define list_insert(list, elem)         _list_insert_rear((_list_t*)(list), (elem))
#define list_insert_next(list,cur,elem) _list_insert_next((_list_t*)(list), (cur), (elem))
#define list_insert_prev(list,cur,elem) _list_insert_prev((_list_t*)(list), (cur), (elem))
/*
#define list_next(elem)         ((((_list_elem_t*)((char*)elem-2*sizeof(_list_elem_t*)))->next)->elem)
#define list_prev(elem)         ((((_list_elem_t*)((char*)elem-2*sizeof(_list_elem_t*)))->prev)->elem)

#define list_forward(list, elem)        (((_bs_list_elem_t*)list_addr(elem))->next!=(list)->rear)
#define list_insert_next(list, curelem, elem)   _bs_list_insert_next((_bs_list_t*)list, curelem, elem);
#define list_insert_prev(list, curelem, elem)   _bs_list_insert_prev((_bs_list_t*)list, curelem, elem);
*/

int _list_insert_head(_list_t* list, void* elem);
int _list_insert_rear(_list_t* list, void* elem);
int _list_insert_next(_list_t* list, void* cur, void* elem);
int _list_insert_prev(_list_t* list, void* cur, void* elem);
int _list_free(_list_t* list);

/* 静态链表 */
#define ring_t(type, size)      struct{ \
}
/* hash */
typedef struct _bs_hash_t      _bs_hash_t;
typedef _bs_hash_t               hash_t;
typedef struct _bs_hash_node_t _bs_hash_node_t;
typedef int (* _bs_hash_f)(char* str, int len);

#define BYTE_BITS               8
struct _bs_hash_t{
    int                 size;
    _bs_hash_node_t*    hash;
};

struct _bs_hash_node_t{
    uint32_t            hsign;
    uint32_t            lhigh;
    int                 code;
    _bs_hash_node_t*    next;
};
    
/* map */
/*
typedef struct _bs_map_t       _bs_map_t;
typedef _bs_map_t               map_t;
typedef struct _bs_map_node_t  _bs_map_node_t;

struct _bs_map_t{
    int                 size;
    _bs_map_node_t*     map;
};

struct _bs_map_node_t{
    uint32_t            hsign;
    uint32_t            lsign;
    int                 code;
    void*               key;
    size_t              keysize;
    void*               val;
    size_t              valsize;
    _bs_map_node_t*     next;
}

#define map_init(map, size)     _bs_map_init((_bs_map_t*)(map), (size));
#define map_add(map, key, val)  _bs_map_add((map), (key), sizeof(*(key)), (val), sizeof(*(val)));
#define map_srch(map, key, val) _bs_map_srch((map), (key), sizeof(*(key)), (val));

int _bs_map_init(_bs_map_t* map, int size);
int _bs_map_add(_bs_map_t* map, void* key, size_t keysize, void* val, size_t valsize);
int _bs_map_srch(_bs_map_t* map, void* key, size_t keysize, void* val);
*/

#ifdef __cplusplus
}
#endif
#endif
